const NUM_PARTICLES = 1000;

var DRAG = 0.005,
  i;
var { initPointList } = require("../../points")
var { Point } = require("../../Point");
var Distances = require("../../lib/distances");
const { Plot } = require("../../plot");
Distances.setNUM_PARTICLES(NUM_PARTICLES)
var plot = new Plot(document.querySelector("#myCanvas"));

var list = initPointList(NUM_PARTICLES);

list.forEach(v => {
  v.p = Math.sin(Math.random() * Math.PI * 2)
})

global.list = list
var distance = new Array(NUM_PARTICLES)

var orgv2 = new Array(NUM_PARTICLES);//能量

var grev = 0.3; var repu = 1.5;

'use strict'
function step() {
  var lastXY = list.map(v => {
    return { x: v.x, y: v.y }
  })
  let sumd = 0;
  for (i = 0; i < NUM_PARTICLES; i++) {
    let p = list[i];
    for (let j = 0, length2 = NUM_PARTICLES; j < length2; j++) {
      var tem = list[j];
      distance[j] = Point.len(lastXY[j], lastXY[i]);

      orgv2[j] = 0.5 * (tem.vx * tem.vx + tem.vy * tem.vy);
      sumd += distance[j];
    }
    let pv2 = orgv2[i]

    if (pv2 > 10000) {
      // 能量转移阙值,损失36%
      p.vx = 0.8 * p.vx;
      p.vy = 0.8 * p.vy;
      var k = 0.36 * pv2 / sumd * NUM_PARTICLES;//转移动能
      for (let j = 0, length2 = NUM_PARTICLES; j < length2; j++) {
        //if(k>10)
        if (orgv2[j] > 0 && distance[j] > 0) {
          /* if(orgv2[j]<pv2){*/
          let tmpk = Math.sqrt(k / distance[j] / orgv2[j]);
          list[j].vx = Math.sqrt(1 + tmpk) * list[j].vx;
          list[j].vy = Math.sqrt(1 + tmpk) * list[j].vy;
          //   }
        }
      }
    }

    for (let j = 0, length2 = NUM_PARTICLES; j < length2; j++) {
      let pv = { dvx: p.x - list[j].x, dvy: p.y - list[j].y };
      let dist1 = distance[j];
      if (distance[j] == 0||i==j) {
        continue
      }

      if ((distance[j] > 100)) {
        list[i].vx -= pv.dvx / dist1 * grev + (Math.sin(dist1) + 0.5) * 13;
        list[j].vx += pv.dvx / dist1 * grev + (Math.sin(dist1) + 0.5) * 13;
        list[j].vy += pv.dvy / dist1 * grev + (Math.sin(dist1) + 0.5) * 13; 
        list[i].vy -= pv.dvy / dist1 * grev + (Math.sin(dist1) + 0.5) * 13; 
      } else if (distance[j] < 100) {
        list[j].vx -= pv.dvx / dist1 * repu;
        list[j].vy -= pv.dvy / dist1 * repu;

        list[i].vx += pv.dvx / dist1 * repu;
        list[i].vy += pv.dvy / dist1 * repu;
      }
    }
    p.x += (p.vx *= 0.001)
    p.y += (p.vy *= 0.001)
  }
  plot.drawList(list)
}



function step2() {
  const distances = Distances.getDistances(list)
  for (i = 0; i < NUM_PARTICLES; i++) {
    let p = list[i];
    var distance = distances[i]
    for (let j = 0, length2 = NUM_PARTICLES; j < length2; j++) {
      let pv = { dvx: p.x - list[j].x, dvy: p.y - list[j].y };
      let dist1 = distance[j];
      // if ((distance[j] > 100)) {
      list[j].vx += pv.dvx * grev * Math.sin((dist1 - 2) * (dist1 - 9) * dist1 * 0.000001);
      list[j].vy += pv.dvy * grev * Math.sin((dist1 - 2) * (dist1 - 9) * dist1 * 0.000001);
      // } else if (distance[j] < 100) {
      //    [j].vx -= pv.dvx / dist1 * repu;
      //   list[j].vy -= pv.dvy / dist1 * repu;
      // }
    }
    p.x += (p.vx *= DRAG)
    p.y += (p.vy *= DRAG)
  }
  plot.drawList(list)
}

function step4() {
  grev = 10000
  const distances = Distances.getDistances(list)
  for (i = 0; i < NUM_PARTICLES; i++) {
    let p = list[i];
    distance = distances[i]
    for (let j = 0, length2 = NUM_PARTICLES; j < length2; j++) {
      if (i == j) {
        continue;
      }
      let pv = { dvx: p.x - list[j].x, dvy: p.y - list[j].y };
      let dist1 = distance[j];

      list[j].vx += pv.dvx * ((Math.sin(dist1) * 20 + 13) + 10000 / dist1 * dist1)
      list[j].vy += pv.dvy * ((Math.sin(dist1) * 20 + 13) + 10000 / dist1 * dist1)

    }
    p.x += (p.vx *= DRAG)
    p.y += (p.vy *= DRAG)
  }
  plot.drawList(list);
}




function step5() {
  const distances = Distances.getDistances(list)
  const lastXY = list.map(v => {
    return { x: v.x, y: v.y }
  })
  for (i = 0; i < NUM_PARTICLES; i++) {

    let p = lastXY[i];

    for (let j = i + 1, length2 = NUM_PARTICLES; j < length2; j++) {
      let pv = { dvx: p.x - lastXY[j].x, dvy: p.y - lastXY[j].y };
      let dist1 = distances[i][j];
      list[j].vx += pv.dvx / dist1 * (0.07 + Math.cos(dist1) * 0.13);
      list[j].vy += pv.dvy / dist1 * (0.07 + Math.cos(dist1) * 0.13);

      list[i].vx -= pv.dvx / dist1 * (0.07 + Math.cos(dist1) * 0.13);
      list[i].vy -= pv.dvy / dist1 * (0.07 + Math.cos(dist1) * 0.13);
    }

    p.x += (p.vx *= DRAG)
    p.y += (p.vy *= DRAG)
  }
  plot.drawList(list)

}

function step6() {
  const distances = Distances.getDistances(list)
  const lastXY = list.map(v => {
    return { x: v.x, y: v.y }
  })
  for (i = 0; i < NUM_PARTICLES; i++) {
    let p = list[i];
    for (let j = 0, length2 = NUM_PARTICLES; j < length2; j++) {
      let pv = { dvx: p.x - lastXY[j].x, dvy: p.y - lastXY[j].y };
      
      let dist1 = distances[i][j];
      if (dist1 == 0) {
        continue
      }
      if (isNaN (dist1) ) {
        // continue
        debugger
      }
      var pw = list[j].e ^ list[i].e
      // list[j].vx += pv.dvx / dist1 * (-7 + dist1 * 1.3 + 1 / dist1 ** 2 * pw);
      // list[j].vy += pv.dvy / dist1 * (-7 + dist1 * 1.3 + 1 / dist1 ** 2 * pw);

      // list[i].vx -= pv.dvx / dist1 * (-7 + dist1 * 1.3 + 1 / dist1 ** 2 * pw);
      // list[i].vy -= pv.dvy / dist1 * (-7 + dist1 * 1.3 + 1 / dist1 ** 2 * pw);

      //  list[j].vx += pv.dvx / dist1 * (Math.atan(dist1-1));
      //  list[j].vy += pv.dvy / dist1 * (Math.atan(dist1-1));

      //  list[i].vx -= pv.dvx / dist1 * (Math.atan(dist1-1));
      //  list[i].vy -= pv.dvy / dist1 * (Math.atan(dist1-1));


      list[j].vx += pv.dvx / dist1 / dist1 * pw;

      list[j].vy += pv.dvy / dist1 / dist1 * pw;
      list[i].vx -= pv.dvx / dist1 / dist1 * pw;

      list[i].vy -= pv.dvy / dist1 / dist1 * pw;

      /*      list[j].vx += pv.dvx / dist1 / (7 - dist1 * 1.3) * 100;
              list[j].vy += pv.dvy / dist1 / (7 - dist1 * 1.3) * 100;
      
              list[i].vx -= pv.dvx / dist1 / (7 - dist1 * 1.3) * 100;
              list[i].vy -= pv.dvy / dist1 / (7 - dist1 * 1.3) * 100; */

      list[j].vx += pv.dvx / dist1 * (Math.tan(Math.sin(dist1)) ** 2 - 0.5)
      list[j].vy += pv.dvy / dist1 * (Math.tan(Math.sin(dist1)) ** 2 - 0.5)

      list[i].vx -= pv.dvx / dist1 * (Math.tan(Math.sin(dist1)) ** 2 - 0.5)
      list[i].vy -= pv.dvy / dist1 * (Math.tan(Math.sin(dist1)) ** 2 - 0.5)
    }
    var sumkin = 0;
    for (var j = 0; j < NUM_PARTICLES; j++){
      var tem = list[j];
      sumkin += 0.5 * (tem.vx * tem.vx + tem.vy * tem.vy);
    }
    console.log(sumkin)

    p.x += (p.vx *= DRAG)
    p.y += (p.vy *= DRAG)
  }
  plot.drawList(list)

}
// 旋转
function step7() {
  const distances = Distances.getDistances(list)
  const lastXY = list.map(obj => {
    return {
      x: obj.x, y: obj.y,
      vx: obj.vx, vy: obj.vy,
      // v: Math.sqrt(obj.x ** 2 + obj.y ** 2) 
    }
  })
  for (i = 0; i < NUM_PARTICLES; i++) {
    let p = list[i];
    for (let j = i + 1, length2 = NUM_PARTICLES; j < length2; j++) {

      var pw = list[j].e ^ list[i].e

      let pv = { dvx: p.x - lastXY[j].x, dvy: p.y - lastXY[j].y };
      let dist1 = distances[i][j];

      list[j].vx += pv.dvx / dist1 / dist1;
      list[j].vy += pv.dvy / dist1 / dist1;


      list[i].vx -= pv.dvx / dist1 / dist1;
      list[i].vy -= pv.dvy / dist1 / dist1;

      list[j].vx += 0.01 * pv.dvy ;
      list[j].vy -= 0.01 * pv.dvx ;

      list[i].vx -= 0.01 * pv.dvy ;
      list[i].vy += 0.01 * pv.dvx ;
    }

    p.x += (p.vx *= DRAG)
    p.y += (p.vy *= DRAG)
  }
  plot.drawList(list)
}



setInterval(step2, 10);
module.exports = { list }
